#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <list>
#include <memory>
#include <complex>
#include <algorithm>
#include <cassert>
#include <cstddef>
#include "include/pool/threadpool.h"
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <atomic>

//有些场景，希望线程执行任务返回返回值
//main thread
using namespace std;
class CountTask:public Task{
 private:
 int begin_;
 int end_;   
 public:
    //问题一，怎么设计返回值，可以表示任意的类型？ 
    //java类型 Object类型是所有类类型的基类
    //c++ 17 Any类型 -> 自己实现   // 模版 基类类型指向派生类型
    //c++ 20 semaphore信号量类型 -> 自己实现（mutex+条件变量），任意的其它类型
    Any run(){
       int countTotal =0; 
       for (int i = begin_; i < end_; i++)
       {
        countTotal+=i;
       }
       cout << "counttotal:" << countTotal <<endl;
       return countTotal;
    };   
    CountTask(int begin,int end):begin_(begin),end_(end){

    }
};
//lock 悲观锁
//CAS(V, Expected, New)：乐观锁
//检查内存地址V的当前值是否等于Expected
//若相等，将V更新为New
//返回操作是否成功（否则重试或放弃）
//


//线程池执行流程
//1.生产者：用户提交任务，任务Task 对象，并返回Result对象 ，result里的task对象在用户提交任务赋值
//2.消费者：线程池处理任务，处理Task 对象，并为task里的result对象 赋值
//3.result.get() 阻塞住，等待着消费者处理完
//4.result.setvalue() 设置完值 ，通知result.get()能获取到值了

//生成Result对象时需要传入对应的task，并把自身设置给task（关键步骤，相当于双向绑定）
// Result::Result(std::shared_ptr<Task> task, bool isValid) : task_(task), isValid_(isValid)
// {
//     task_->setResult(this);
// };

//问题:ThreadPool对象析构以后，怎么样吧线程池相关的线程资源全部回收
int main(){
    {
    ThreadPool threadPool;
    threadPool.setMode(PoolMode::CACHED);
    threadPool.start(2);
    Result res1 = threadPool.submitTask(make_shared<CountTask>(1,200));
    Result res2 = threadPool.submitTask(make_shared<CountTask>(200,500));
    Result res3 = threadPool.submitTask(make_shared<CountTask>(500,1001));
    int count1  = res1.get().cast_<int>();
    int count2  = res2.get().cast_<int>();
    int count3  = res3.get().cast_<int>();
    cout << (count1+count2+count3) <<endl;
    }
    // int count1  = res1.get().cast_<int>();
    // int count2  = res2.get().cast_<int>();
    // int count3  = res3.get().cast_<int>();
    // cout << (count1+count2+count3) <<endl;
    cout << "main over"<<endl;
    return 0;
}